package com.wujunshen.dumpling.database.mysql.common;

import com.wujunshen.dumpling.common.utils.FileUtils;
import com.wujunshen.dumpling.core.Configuration;
import com.wujunshen.dumpling.core.engine.EngineConfig;
import com.wujunshen.dumpling.core.engine.EngineFileType;
import com.wujunshen.dumpling.core.engine.EngineTemplateType;
import com.wujunshen.dumpling.core.execute.DocumentationExecute;
import com.wujunshen.dumpling.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.SneakyThrows;

import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

import static com.wujunshen.dumpling.database.mysql.common.Constants.FILE_OUTPUT_DIR;

/** 数据库文档生成基类 */
public abstract class AbstractDocumentationExecute implements IProperties {
  /**
   * 生成
   *
   * @param configuration {@link Configuration}
   */
  public void execute(Configuration configuration) {
    new DocumentationExecute(configuration).execute();
  }

  @SneakyThrows
  public DataSource getDataSource() {
    File path =
        FileUtils.getFileByPath(
            FILE_OUTPUT_DIR + "/src/test/resources/properties/mysql.properties");
    Properties properties = new Properties();
    FileInputStream inputStream = new FileInputStream(Objects.requireNonNull(path));
    properties.load(inputStream);

    // 数据源
    HikariConfig config = new HikariConfig();
    config.setDriverClassName(getDriver(properties));
    config.setJdbcUrl(getUrl(properties));
    config.setUsername(getUserName(properties));
    config.setPassword(getPassword(properties));
    // 设置可以获取tables备注信息
    config.addDataSourceProperty("useInformationSchema", "true");
    config.setMinimumIdle(2);
    config.setMaximumPoolSize(5);
    return new HikariDataSource(config);
  }

  /**
   * 生成配置
   *
   * @param engineFileType 生成文件类型
   * @param engineTemplateType 使用生成模板类型
   * @return EngineConfig
   */
  public EngineConfig getEngineConfig(
      EngineFileType engineFileType, EngineTemplateType engineTemplateType) {
    return EngineConfig.builder()
        // 生成文件路径
        .fileOutputDir(FILE_OUTPUT_DIR)
        // 打开目录
        .openOutputDir(true)
        // 文件类型
        .fileType(engineFileType)
        // 生成模板实现
        .produceType(engineTemplateType)
        .build();
  }

  /**
   * 配置
   *
   * @param engineConfig EngineConfig
   * @return Configuration
   */
  public Configuration config(EngineConfig engineConfig) {
    return Configuration.builder()
        // 版本
        .version("1.0")
        // 描述
        .description("数据字典")
        // 数据源
        .dataSource(getDataSource())
        // 生成配置
        .engineConfig(engineConfig)
        // 生成配置
        .produceConfig(setIgnoreSetting())
        .build();
  }

  /**
   * 设置忽略表配置
   *
   * @return ProcessConfig
   */
  public ProcessConfig setIgnoreSetting() {
    List<String> ignoreTableName = new ArrayList<>();
    ignoreTableName.add("test");
    // 忽略表前缀
    List<String> ignorePrefix = new ArrayList<>();
    ignorePrefix.add("test");
    // 忽略表后缀
    List<String> ignoreSuffix = new ArrayList<>();
    ignoreSuffix.add("test");
    return ProcessConfig.builder()
        // 忽略表名
        .ignoreTableName(ignoreTableName)
        // 忽略表前缀
        .ignoreTablePrefix(ignorePrefix)
        // 忽略表后缀
        .ignoreTableSuffix(ignoreSuffix)
        .build();
  }
}
